package org.easy.excel.support.config.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.write.handler.WriteHandler;
import lombok.Getter;
import org.easy.excel.support.annotations.ExportTopLabel;
import org.easy.excel.support.config.AnnotationExcelConfig;
import org.easy.excel.support.config.ExcelConfig;
import org.easy.excel.support.config.entity.TitleConfig;
import org.easy.excel.support.parse.AnnotationExcelSourceParse;
import org.easy.excel.support.parse.source.ExcelTopLabelSource;
import org.easy.excel.support.parse.source.ExportLabelSource;

import java.time.LocalDateTime;
import java.util.*;

/**
 * {@link ExcelConfig} 的抽象实现类，用于解析注解类型的数据导出
 *
 * @author 李坤
 * @date 2022/6/8 22:42
 */
public abstract class AbstractAnnotationExcelConfig implements AnnotationExcelConfig {

    /**
     * 导出实体类的类型
     */
    @Getter
    protected Class<?> sourceClass;

    /**
     * Excel导出样式拦截器
     */
    @Getter
    protected List<WriteHandler> writeHandlerList;

    /**
     * 解析后的数据
     */
    @Getter
    protected List<List<String>> excelExportDataList;

    /**
     * 标题配置信息
     */
    @Getter
    protected TitleConfig titleConfig = new TitleConfig();

    /**
     * 注解的数据源解析器
     */
    @Getter
    protected AnnotationExcelSourceParse annotationExcelSourceParse;

    @Override
    public String getFileName() {
        // 如果给定的类型为一个 "正常的" 类（实体类），则尝试解析其注解获取文件名
        if (Objects.nonNull(sourceClass) && !Collection.class.isAssignableFrom(sourceClass) && !Map.class.isAssignableFrom(sourceClass)) {
            final ExcelTopLabelSource excelTopLabelSource = annotationExcelSourceParse.getExcelTopTitle(sourceClass);

            String fileName = excelTopLabelSource.getFileName();
            fileName = StrUtil.isNotEmpty(fileName) ? fileName : excelTopLabelSource.getTopTitle();

            // 获取 ExportTopLabel 注解上的文件名称，如果不存在，则使用当前时间
            return StrUtil.isNotEmpty(fileName) ? fileName : LocalDateTime.now().toString();
        }
        return LocalDateTime.now().toString();
    }

    @Override
    public String getSheetName() {
        String sheetName = ExportTopLabel.DEFAULT_SHEET_NAME;

        // 如果给定的类型为一个 "正常的" 类（实体类），则尝试解析其注解获取文件名
        if (Objects.nonNull(sourceClass) && !Collection.class.isAssignableFrom(sourceClass) && !Map.class.isAssignableFrom(sourceClass)) {
            sheetName = annotationExcelSourceParse.getExcelTopTitle(sourceClass).getSheetName();
        }
        return sheetName;
    }

    @Override
    public List<List<String>> getExcelExportHeaderList() {
        List<List<String>> excelExportHeaderList = new ArrayList<>();

        // 如果给定的类型为一个 "正常的" 类（实体类），则尝试解析其注解获取文件名
        if (Objects.nonNull(sourceClass) && !Collection.class.isAssignableFrom(sourceClass) && !Map.class.isAssignableFrom(sourceClass)) {
            int headerListSize;
            excelExportHeaderList = annotationExcelSourceParse.getSourceTitles(sourceClass);
            final ExcelTopLabelSource excelTopLabelSource = annotationExcelSourceParse.getExcelTopTitle(sourceClass);
            final List<ExportLabelSource> annotationExcelSourceList = annotationExcelSourceParse.getAnnotationExcelSourceList(sourceClass);

            if (Objects.nonNull(excelExportHeaderList) && (headerListSize = excelExportHeaderList.size()) > 0) {
                // 设置 标题的配置信息
                titleConfig.setTopTitleColumns(StrUtil.isNotEmpty(excelTopLabelSource.getTopTitle()) ? excelTopLabelSource.getHighly() : 0);

                final List<List<String>> middleHeaderList;
                if (ObjectUtil.isNotEmpty(middleHeaderList = getExcelMiddleHeaderList(headerListSize))) {
                    titleConfig.setSecondaryTitleColumns(middleHeaderList.get(0).size() + titleConfig.getTopTitleColumns());

                    // 将自定义的中间标题信息添加到最终的标题信息中
                    for (int index = 0; index < headerListSize; index++) {
                        final List<String> innerHeaders = excelExportHeaderList.get(index);
                        final List<String> titleList = annotationExcelSourceList.get(index).getTitles();

                        innerHeaders.addAll(innerHeaders.size() - titleList.size(), middleHeaderList.get(index));
                    }
                }
            } else {
                final int size = excelTopLabelSource.isAppendSequence() ? annotationExcelSourceList.size() + 1 : annotationExcelSourceList.size();
                if ((ObjectUtil.isNotEmpty(excelExportHeaderList = getExcelMiddleHeaderList(size)))) {
                    titleConfig.setSecondaryTitleColumns(excelExportHeaderList.get(0).size());
                }
            }
            if (ObjectUtil.isNotEmpty(excelExportHeaderList)) {
                titleConfig.setFieldTitleColumns(excelExportHeaderList.get(0).size());
            }
        }
        // 添加用户自定义标题信息
        processHeaderListAfterParse(excelExportHeaderList);
        if (ObjectUtil.isNotEmpty(excelExportHeaderList)) {
            titleConfig.setLowestLevelTitleColumns(excelExportHeaderList.get(0).size());
        }
        return excelExportHeaderList;
    }


    /*------------------------------------------------protected method------------------------------------------------*/


    /**
     * 后置自定义表头处理方法
     *
     * @param excelExportHeaderList 解析后的表头列
     */
    protected void processHeaderListAfterParse(List<List<String>> excelExportHeaderList) {
    }

    /**
     * 根据底层标题每行数据的长度返回中间部分的标题配置列
     *
     * @param length 底层标题每行数据的长度
     *
     * @return 中间部分的标题配置列
     */
    protected List<List<String>> getExcelMiddleHeaderList(int length) {
        return Collections.emptyList();
    }
}
